package com.ruoyi.parttime.controller;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.kafka.KafkaProducer;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.parttime.domain.ApplyForParrtime;
import com.ruoyi.parttime.domain.ParttimePlaza;
import com.ruoyi.parttime.domain.ParttimePublish;
import com.ruoyi.parttime.service.IApplyForParrtimeService;
import com.ruoyi.parttime.service.IParttimePlazaService;
import com.ruoyi.parttime.service.IParttimePublishService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 兼职广场Controller
 *
 * @author ruoyi
 * @date 2024-04-02
 */
@RestController
@RequestMapping("/user/plaza")
@Api(tags = "兼职广场")
public class ParttimePlazaController extends BaseController {
    @Autowired
    private IParttimePlazaService parttimePlazaService;

    @Autowired
    private IApplyForParrtimeService applyForParrtimeService;

    @Autowired
    private IParttimePublishService parttimePublishService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    KafkaProducer kafkaProducer;

    /**
     * 查询兼职广场列表
     */
    @PreAuthorize("@ss.hasPermi('common:plaza:list')")
    @ApiOperation(value = "查询所有兼职信息")
    @GetMapping("/list")
    public TableDataInfo list(ParttimePlaza parttimePlaza) {
        startPage();
        List<ParttimePlaza> list = parttimePlazaService.selectParttimePlazaList(parttimePlaza);
        return getDataTable(list);
    }

    /**
     * top榜单,获取热度为前5的兼职
     */
    @PreAuthorize("@ss.hasPermi('common:plaza:top')")
    @ApiOperation(value = "top榜单")
    @GetMapping("/top")
    public AjaxResult selectParttimePublishTop() {
        return success(parttimePlazaService.selectParttimePublishTop());
    }

    /**
     * 导出兼职信息
     */
    @PreAuthorize("@ss.hasPermi('common:plaza:export')")
    @Log(title = "兼职广场", businessType = BusinessType.EXPORT)
    @ApiOperation(value = "导出兼职信息")
    @PostMapping("/export")
    public void export(HttpServletResponse response, ParttimePlaza parttimePlaza) {
        List<ParttimePlaza> list = parttimePlazaService.selectParttimePlazaList(parttimePlaza);
        ExcelUtil<ParttimePlaza> util = new ExcelUtil<>(ParttimePlaza.class);
        util.exportExcel(response, list, "兼职广场的兼职数据");
    }

    /**
     * 获取兼职广场详细信息
     */
    @PreAuthorize("@ss.hasPermi('common:plaza:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(parttimePlazaService.selectParttimePlazaById(id));
    }

    /**
     * 申请兼职
     */
    @PreAuthorize("@ss.hasPermi('common:plaza:add')")
    @Log(title = "兼职广场", businessType = BusinessType.INSERT)
//    @AccessLimit()
    @ApiOperation(value = "申请兼职")
    @PostMapping
    public AjaxResult add(@RequestBody ApplyForParrtime apply) {
        //获取用户id
        String userId = SecurityUtils.getUserId().toString();
        //获取请求的兼职对应的id
        String value = apply.getParttimePublishId().toString();
        String key = userId + "-" + value;
        ParttimePublish parttimePublish = new ParttimePublish();
        //每次执行请求前，通过key判断缓存中是否有相同请求
        if (redisCache.hasKey(key)) {
            return error("您已申请过,请勿重复申请");
        }
        //为了避免当管理员同意了申请后，缓存的数据被移除后，用户再次申请相同的兼职，查询兼职申请成功的数据
        ApplyForParrtime applyForParrtime = applyForParrtimeService.selectApplyForParrtimeBypublishId(apply.getParttimePublishId());
        if (applyForParrtime != null && applyForParrtime.getApplyForStatus() != 2) {
            //在存入缓存,避免再次重复申请
            return error("您已申请过,请勿重复申请");
        }
        //如果都不存在,存入redis中
        redisCache.setHash(key, value);
        //设置超时时间10分钟
        redisCache.expire(key, 10 * 60);
        //每次申请成功对应的兼职之后,都要让被申请的次数加1
        //为了减轻数据库的压力,先将对应的numbers取出,再加1，然后存入缓存，最后在对数据库进行修改
        //定义好键值，为其申请的兼职的id
        String key1 = apply.getParttimePublishId().toString();
        Long num;
        //判断键是否存在，存在则表示这不是第一请求，反之是第一次
        if (!redisCache.hasKey(key1)) {
            parttimePublish = parttimePublishService.selectParttimePublishById(apply.getParttimePublishId());
            //第一次申请取出里numbers加1
            num = parttimePublish.getNumbers() == null ? 1L : parttimePublish.getNumbers() + 1L;
//            value1 = num.toString();
            parttimePublish.setNumbers(num);
            //存入redis中
            redisCache.setCacheObject(key1, num);
            //设置对应的值，用于定时任务的处理
//            Map<String,List<ParttimePublish>> listMap = new HashMap<>();
            Map<String, ParttimePublish> map = new HashMap<>();
            map.put(parttimePublish.getId().toString(), parttimePublish);
            String taskKey = Constants.APPLY_FOR_KEY;
            redisCache.setCacheMap(taskKey, map);
            //设置超时时间10分钟
            redisCache.expire(taskKey, 10 * 60);
            redisCache.expire(key1, 10 * 60);
        } else {
            //取出对应值，加一
            num = (Long) redisCache.getCacheObject(key1) + 1L;
//            value1 = num.toString();
            parttimePublish.setNumbers(num);
            //存入redis中
            redisCache.setCacheObject(key1, num);
        }
        kafkaProducer.sendMessage("my_topic", "兼职数据发生更新");
        return toAjax(applyForParrtimeService.insertApplyForParrtime(apply));
    }
}
